package cn.wit.sst.view;

import java.util.List;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Controller;

import cn.wit.sst.components.ChartHelper;
import cn.wit.sst.domain.College;
import cn.wit.sst.domain.Major;
import cn.wit.sst.dto.ClazzQuery;
import cn.wit.sst.dto.ScoreRankDto;
import cn.wit.sst.service.ClazzService;
import cn.wit.sst.utils.AppCache;
import cn.wit.sst.utils.Dialogs;
import io.reactivex.Observable;
import io.reactivex.rxjavafx.schedulers.JavaFxScheduler;
import io.reactivex.schedulers.Schedulers;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Spinner;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.VBox;
import javafx.util.StringConverter;

@Controller
public class ClazzController {
	private static final Logger logger = LoggerFactory.getLogger(StudentController.class);
	@FXML ChoiceBox<College> choiceCollege;
	@FXML ChoiceBox<Major> choiceMajor;
	@FXML Spinner<Integer> spinnerYear;
	@FXML ToggleGroup grpGrade;
	@FXML ToggleGroup grpSemester;

	@FXML RadioButton radioGrade1;
	@FXML RadioButton radioGrade2;
	@FXML RadioButton radioGrade3;
	@FXML RadioButton radioGrade4;
	@FXML RadioButton radioSemester1;
	@FXML RadioButton radioSemester2;
	@FXML Spinner<Integer> spinnerClazz;
	@FXML VBox chartContainer;

	@Autowired
	AppCache cache;

	@Autowired
	ClazzService clazzService;
	@FXML
	public void initialize() {
		radioGrade1.setUserData(0);
		radioGrade2.setUserData(1);
		radioGrade3.setUserData(2);
		radioGrade4.setUserData(3);

		radioSemester1.setUserData(1);
		radioSemester2.setUserData(2);

		choiceCollege.setConverter(new StringConverter<College>() {
			@Override
			public String toString(College object) {
				return object.getName();
			}

			@Override
			public College fromString(String string) {
				return null;
			}
		});
		// 选中学院时、查询对应的专业
		choiceCollege.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
			Observable.just(newValue.getId())
				.observeOn(Schedulers.computation())
				.map(id -> clazzService.selectMajorByCollegeId(id))
				.observeOn(JavaFxScheduler.platform())
				.subscribe(items -> {
					choiceMajor.getItems().clear();
					choiceMajor.getItems().addAll(items);
					choiceMajor.getSelectionModel().selectFirst();
				});
		});

		choiceMajor.setConverter(new StringConverter<Major>() {
			@Override
			public String toString(Major object) {
				return object.getName();
			}

			@Override
			public Major fromString(String string) {
				return null;
			}
		});
	}

	@EventListener
	public void onCacheReadyEvent(AppCache.CacheReadyEvent event) {
		choiceCollege.getItems().addAll(cache.getColleges());
		choiceCollege.getItems().stream()
			.filter(item -> "理学院".equals(item.getName()))
			.findFirst()
			.ifPresent(item -> {
				choiceCollege.getSelectionModel().select(item);
			});
	}

	@FXML public void handSearchAction(ActionEvent event) {
		chartContainer.getChildren().clear();
		Observable.just(getQuery())
			.observeOn(Schedulers.computation())
			.map(q -> clazzService.search(q))
			.observeOn(JavaFxScheduler.platform())
			.subscribe(items -> {
				if (items.isEmpty()) {
					Dialogs.info("没有相关信息！");
				} else {
					items.entrySet().forEach(e -> showLineChart(e));
				}
			});
	}

    private void showLineChart(Entry<Long, List<ScoreRankDto>> entry) {
    	Node chart = ChartHelper.createLineChart(
    			cache.getCourse(entry.getKey()).getName(),	// 课程名作为标题
    			entry.getValue()		// 分数集合
    	);
    	chartContainer.getChildren().add(chart);
	}

	private ClazzQuery getQuery() {
    	Major item = choiceMajor.getSelectionModel().getSelectedItem();
    	if (item == null) {
    		Dialogs.alert("请选中专业！");
    		return null;
    	}

    	Integer year = spinnerYear.getValue();
    	if (year == null) {
    		Dialogs.alert("请输入学年！");
    		return null;
    	}

    	Integer clazz = spinnerClazz.getValue();
    	if (clazz == null) {
    		Dialogs.alert("请输入班级！");
    		return null;
    	}

    	int grade = (int) grpGrade.getSelectedToggle().getUserData();
    	int semester = (int) grpSemester.getSelectedToggle().getUserData();
    	logger.info("查询条件：学年【{}】，学期【{}】", grade, semester);

    	ClazzQuery query = new ClazzQuery();
    	query.setMid(item.getId());
    	query.setGrade(grade);
    	query.setSemester(semester);
    	query.setYear(Integer.valueOf(year));
    	query.setClazz(clazz);

    	return query;
    }
}
